package com.amat0urheu.service.impl;

import com.amat0urheu.controller.ExperimentFileController;
import com.amat0urheu.dao.ExperimentsMapper;
import com.amat0urheu.dao.FileMapper;
import com.amat0urheu.dao.UploadFileDao;
import com.amat0urheu.pojo.*;
import com.amat0urheu.pojo.CloudPojo.OpenStack;
import com.amat0urheu.service.UploadService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.amat0urheu.service.UploadFileService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;



@Service("uploadFileService")
public class UploadFileServiceImpl extends ServiceImpl<UploadFileDao, UploadFile> implements UploadFileService {
    @Autowired
    FileMapper fileMapper;
    @Value("${file.path}")
    private String savePath;

    @Override
    public ReturnRes selectAllExperimentFile(int pageSize, int pageNum) {
        PageHelper.startPage(pageNum, pageSize);
        List<UploadFile> uploadFiles =fileMapper.selectAllExperimentFile();

        if (uploadFiles != null) {
            return new ReturnRes(true, new PageInfo<>(uploadFiles), "查询成功");
        }
        return new ReturnRes(false, "查询失败");
    }

    @Override
    public ReturnRes downloadFile(String fileId, HttpServletResponse response) {
        response.reset();
        UploadFile file = super.getById(fileId);
        if (file == null) {
            return new ReturnRes(false, "文件不存在");
        }
        FileInputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            inputStream = new FileInputStream(new File(savePath + file.getFilePath()));
            // 下载方式 文件名应该编码成UTF-8
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(file.getFileName(), "UTF-8"));
            byte[] buffer = new byte[1024];
            int len;
            outputStream = response.getOutputStream();
            while ((len = inputStream.read(buffer)) > 0) {


                outputStream.write(buffer, 0, len);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return new ReturnRes(false);
    }

    @Override
    public ResponseEntity<byte[]> downLoadExperimentFiles() {
        System.out.println("kaishi xia zai ");
        try {
            // 1. 创建临时目录
            Path tempDirectory = Files.createTempDirectory("experiments");

            // 2. 遍历每个同学的实验文件，按实验分类存放到临时目录中的相应文件夹下
            List<StudentExperiment> experiments = getStudentExperiments(); // 你的方法获取实验数据的逻辑
            for (StudentExperiment experiment : experiments) {
                Path experimentDirectory = tempDirectory.resolve(experiment.getName());
                Files.createDirectories(experimentDirectory);
                copyFilesToDirectory(experiment.getFiles(), experimentDirectory);
            }

            // 3. 压缩文件夹
            Path zipFilePath = tempDirectory.resolve("experiments.zip");
            zipDirectory(tempDirectory, zipFilePath);

            // 4. 返回给前端
            byte[] zipFileBytes = Files.readAllBytes(zipFilePath);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDispositionFormData("attachment", "experiments.zip");
            return new ResponseEntity<>(zipFileBytes, headers, HttpStatus.OK);

        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    private void copyFilesToDirectory(List<File> files, Path destinationDirectory) throws IOException {
        for (File file : files) {
            try {
                Path destinationFile = destinationDirectory.resolve(file.getName());
                Files.copy(file.toPath(), destinationFile, StandardCopyOption.REPLACE_EXISTING);
            }catch (Exception e){
                System.err.println("文件不存在");
                continue;
            }

        }
    }

    private void zipDirectory(Path sourceDirectory, Path zipFilePath) throws IOException {
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFilePath.toFile()))) {
            Files.walk(sourceDirectory)
                    .filter(path -> !Files.isDirectory(path))
                    .forEach(path -> {
                        try {
                            String relativePath = sourceDirectory.relativize(path).toString();
                            zipOutputStream.putNextEntry(new ZipEntry(relativePath));
                            Files.copy(path, zipOutputStream);
                            zipOutputStream.closeEntry();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    });
        }
    }
    @Autowired
    UploadService uploadService;
    @Autowired
    ExperimentsMapper experimentsMapper;
    @Resource
    private UploadFileDao uploadFileDao;
    // 这是一个示例方法，用于获取学生实验数据
    private List<StudentExperiment> getStudentExperiments() {
        // 实现获取学生实验数据的逻辑
        // 返回每个学生的实验数据，包括实验名称和文件列表
        // 示例数据仅供参考
        List<StudentExperiment> experiments = new ArrayList<>();
        List<Experiment> allExperiments = experimentsMapper.getAllExperiments();

        for (int i = 0; i < allExperiments.size(); i++) {
            List<File> fileList=new ArrayList<>();
            List<String> filePathsList = uploadFileDao.getFilePaths(allExperiments.get(i).getEname());
            if( filePathsList.size()!=0){
                for (int j = 0; j < filePathsList.size(); j++) {
                    //添加文件
                    try {
                        fileList.add(new File(savePath+filePathsList.get(j)));
                    }catch (Exception e){
                        System.err.println("文件不存在");
                        continue;
                    }

                }}
            experiments.add(new StudentExperiment(allExperiments.get(i).getEname(),  fileList));
        }

        return experiments;
    }

    // 学生实验类，包含实验名称和文件列表


}
